﻿using System;
using System.Collections.Generic;

namespace FDEE.Model
{
    /// <summary>
    /// PE大类墩柱
    /// </summary>
    internal abstract class CPMBase : ColumnBase
    {
        protected int Width, Length,MidWidth;
        protected int TopWidth, TopMidWidth;
        protected double LenUpper, LenLower; // 花瓶长度
        protected double LenUpperL, LenLowerL; // 花瓶长度
        protected RebarTendonDistribute MainLBarDistribute, AddLBarDistribute;// 顺桥向主筋A截面、加强筋配置规律
        protected RebarTendonDistribute MainWBarDistribute, AddWBarDistribute;// 横桥向主筋A截面、加强筋配置规律
        protected RebarTendonDistribute MainLBarDistributeB, AddLBarDistributeB;// 顺桥向主筋B截面、加强筋配置规律
        protected RebarTendonDistribute MainWBarDistributeB, AddWBarDistributeB;// 横桥向主筋B截面、加强筋配置规律
        protected RebarTendonDistribute MainLBarDistributeC, AddLBarDistributeC;// 顺桥向主筋C截面、加强筋配置规律
        protected RebarTendonDistribute MainWBarDistributeC, AddWBarDistributeC;// 横桥向主筋C截面、加强筋配置规律
        protected double wwSide, llSide;
        protected double Radius,Dia;

        /// <summary>
        /// PME41,PM类墩柱基类
        /// </summary>
        /// <param name="typeName"></param>
        /// <param name="pierNumber"></param>
        /// <param name="ct"></param>
        /// <param name="st"></param>
        /// <param name="ww">下部截面横桥向宽度</param>
        /// <param name="ll">下部截面顺桥向长度</param>
        /// <param name="midww">下部截面中间部分长度</param>
        /// <param name="tww">顶部横桥向宽度</param>
        /// <param name="tmidww">顶部截面中间部分长度</param>
        /// <param name="hh">墩净高</param>
        /// <param name="up">上部加密长度</param>
        /// <param name="low">下部加密长度</param>
        /// <param name="radius">花瓶形状半径</param>
        /// <param name="dia">花瓶圆柱直径</param>
        /// <param name="mainDB">主筋直径</param>
        /// <param name="wwS">斜边w默认100</param>
        /// <param name="llS">斜边l默认150</param>
        internal CPMBase(string typeName, string pierNumber, eColumnType ct, eSubType st,
            int ww, int ll,int midww, int tww,  int tmidww, int hh, double up, double low,double topL, double lowL, double radius,double dia,
            eDB mainDB,double wwS, double llS
            )
            : base(typeName, pierNumber, hh, ct,st, mainDB)
        {
            Width = ww;
            MidWidth = midww;
            Length = ll;
            TopWidth = tww;
            TopMidWidth = tmidww;
            LenUpper = up;
            LenLower = low;
            wwSide = wwS;
            llSide = llS;
            Radius = radius;
            Dia = dia;
            LenUpperL = topL;
            LenLowerL = lowL;
        }

      

        public override void SetConcreteVolume()
        {
            double A = Width * 0.001 * (Length * 0.001)- wwSide*0.001*llSide*0.001;
            double B= Width * 0.001 * (Length * 0.001);
            double C = TopWidth * 0.001 * (Length * 0.001);
            ConcreteVolumn =( A * (PierHeight- LenUpper )+C* LenUpper-(C-B) * LenUpper*0.5) * 0.001;
        }


        /// <summary>
        /// 计算净墩高范围内箍筋数量
        /// </summary>
        /// <param name="UpperSpace">上部间距，默认100mm</param>
        /// <param name="MidSpace">正常间距，默认300mm</param>
        /// <param name="LowerSpace">下部间距，默认100mm</param>
        /// <returns></returns>
        internal int GetStirrupNum(int UpperSpace = 100, int MidSpace = 300, int LowerSpace = 100)
        {
            double npts = 0;
            if ((PierHeight - LenUpper) < 0)
            {
                npts = Math.Round((PierHeight - LenUpper) / LowerSpace, 0, MidpointRounding.AwayFromZero);
            }
            else
            {
                npts = Math.Round(LenLower / LowerSpace, 0, MidpointRounding.AwayFromZero) +
                    Math.Round((PierHeight  - LenUpper) / MidSpace, 0, MidpointRounding.AwayFromZero);
            }
                //+  Math.Round(LenUpper / UpperSpace, 0, MidpointRounding.AwayFromZero);
            return (int)npts+1;
        }
        internal int GetAllStirrupNum(int UpperSpace = 100, int MidSpace = 300, int LowerSpace = 100)
        {
            double npts = 0;
          
                npts = Math.Round((PierHeight - LenUpper-LenLower) / MidSpace + LenLower/ LowerSpace, 0, MidpointRounding.AwayFromZero);
           
            //+  Math.Round(LenUpper / UpperSpace, 0, MidpointRounding.AwayFromZero);
            return (int)npts + 1;
        }
        internal int GetTopStirrupNum(int UpperSpace = 100, int MidSpace = 300)
        {
            double npts = 0;
          
           npts = Math.Round(LenUpperL / UpperSpace, 0, MidpointRounding.AwayFromZero) +
                    Math.Round((LenUpper - LenUpperL) / MidSpace, 0, MidpointRounding.AwayFromZero);
      
            return (int)npts + 1;
        }
        internal int GetLowStirrupNum(int LowerSpace = 100, int MidSpace = 300)
        {
            double npts = 0;

            npts = Math.Round(LenLowerL / LowerSpace, 0, MidpointRounding.AwayFromZero) +
                     Math.Round((PierHeight-LenUpper - LenLowerL) / MidSpace, 0, MidpointRounding.AwayFromZero);

            return (int)npts + 3;
        }
        /// <summary>
        /// 计算边角长度
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        public void CalAngelLength(ref double X, ref double Y)
        {           
            X = 0;
            Y = 0;
            double angle = Math.Atan(llSide / wwSide) * (180.0 / Math.PI);
            X = 50 * Math.Tan((angle * (Math.PI / 180.0) * 0.5));
            Y = 50 * Math.Tan((90 - angle) * (Math.PI / 180.0) * 0.5);
        }

      

        /// <summary>
        /// 根据圆上两点和圆半径 计算圆上任一点x值
        /// </summary>
        /// <param name="x1">圆上第一个点x值</param>
        /// <param name="y1">圆上第一个点x值</param>
        /// <param name="x2">圆上第二个点x值</param>
        /// <param name="y2">圆上第二个点x值</param>
        /// <param name="R">圆半径</param>
        /// <param name="y"></param>
        /// <param name="x"></param>
        public void CalArcCenter(double x1, double y1, double x2, double y2, double R, double y, ref double x, ref double CenterX, ref double CenterY)
        {
            //圆方程(x-CenterX)²+(y-CenterY)²=R²
            CenterX = 0;
            CenterY = 0;//圆心
            //根据数学公式计算
            List<string> CenterList = new List<string>();
            double c1 = (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) / (2 * (x2 - x1));
            double c2 = (y2 - y1) / (x2 - x1);  //斜率
            double A = (c2 * c2 + 1);
            double B = (2 * x1 * c2 - 2 * c1 * c2 - 2 * y1);
            double C = x1 * x1 - 2 * x1 * c1 + c1 * c1 + y1 * y1 - R * R;
            //圆心(应该两个，根据具体情况定)
            //CenterY = (-B - Math.Sqrt(B * B - 4 * A * C)) / (2 * A);
            CenterY = (-B + Math.Sqrt(B * B - 4 * A * C)) / (2 * A);
            CenterX = c1 - c2 * CenterY;

            CenterList.Add(Convert.ToString(CenterX));
            CenterList.Add(Convert.ToString(CenterY));

            //var v = Math.Sqrt(R * R - (y - CenterY) * (y - CenterY));
            //x值
            x = CenterX + Math.Sqrt(R * R - (y - CenterY) * (y - CenterY));
        }

        internal double GetXByH(double x0, double y0, double h0, double R = 4.5)
        {
            double value = Math.Sqrt(R * R - Math.Pow((h0 - y0), 2.0));
            double dd = Math.Max(value + x0, -value + x0);
            return 0.5 * TopWidth  - dd;
        }
       
        internal double GetX2ByH(double x0, double y0, double h0, double R = 4.0)
        {
            double value = Math.Sqrt(R * R - Math.Pow((h0 - y0), 2.0));
            double dd = Math.Max(value + x0, -value + x0);
            return 0.5 * TopWidth- dd;
        }

        /// <summary>
        /// 根据长宽和长宽对应的变化值计算箍筋a,b,c三边的值
        /// </summary>
        /// <param name="W">宽</param>
        /// <param name="L">长</param>
        /// <param name="wwS">宽对应变化长度（宽两端varies）</param>
        /// <param name="llS">长对应变化长度（长两端varies）</param>
        /// <param name="a">六边形a长度</param>
        /// <param name="b">六边形b长度</param>
        /// <param name="c">六边形c长度</param>
        public void CalPara(double W, double L, double wwS, double llS, ref int a, ref int b, ref int c)
        {
            double ang = Math.Atan(llS / Math.Round(wwS, 2)); //A 参考角度
            if (llS == 0)
            {
                //最顶端矩形
                c = (int)(W - 2 * 50 - (int)MainRebarDB * 2);
                b = 0;
                a = (int)(L - 2 * 50 - (int)MainRebarDB * 2);
            }
            else
            {
                //根据三角函数计算三边的值
                double v2 = llS / Math.Sin(ang);

                var v0 = (50 - (50 / Math.Tan(ang)) * Math.Sin(ang)) / Math.Sin(ang);
                double A = W - wwS * 2 - ((50 - (50 / Math.Tan(ang)) * Math.Sin(ang)) / Math.Sin(ang)) * 2;

                ang = Math.Atan(wwS / Math.Round(llS, 2));  //C 参考角度
                var vv1 = (50 - (50 / Math.Tan(ang)) * Math.Sin(ang)) / Math.Sin(ang);
                double C = L - llS * 2 - ((50 - (50 / Math.Tan(ang)) * Math.Sin(ang)) / Math.Sin(ang)) * 2;

                double B = v2 - v0 - vv1;

                c = (int)GlobalFuncs.transmitNum(A);
                b = (int)GlobalFuncs.transmitNum(B);
                a = (int)GlobalFuncs.transmitNum(C);
            }

        }
    }





}
